package com.qianli.cashmama.trade.common.config;

import com.fqgj.common.utils.StringUtils;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Timer;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

/**
 * @Author: cashmama
 * @Date: 2020/12/9-10:50
 * @Description: TODO
 * @Slogan: To be or not to be
 **/
@Component
@Aspect
@Log4j2
public class HttpRequestAop {
    @Pointcut("@annotation(com.qianli.cashmama.trade.common.config.TimerRecord)")
    public void logPointCut() {

    }


    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("== timer around  IN==");
        MethodSignature sign = (MethodSignature) joinPoint.getSignature();
        TimerRecord annotation = sign.getMethod().getAnnotation(TimerRecord.class);
        String method_name = joinPoint.getSignature().getName();


        if (StringUtils.isNotEmpty(annotation.name())) {
            method_name = annotation.name();
        }

        log.info("== timer method_name11 ==,method_name:{}", method_name);

        Timer timer = record(method_name);
        ThrowableHolder holder = new ThrowableHolder();
        Object result = timer.recordCallable(() -> {
            try {
                return joinPoint.proceed();
            } catch (Throwable e) {
                holder.throwable = e;
            }
            return null;
        });
        if (null != holder.throwable) {
            throw holder.throwable;
        }

        return result;
    }

    private class ThrowableHolder {

        Throwable throwable;
    }


    public static Timer record(String method_name) {
        log.info("== timer method_name22 ==,method_name:{}", method_name);

        return Metrics.timer("method.cost.time", "method.name", method_name);

    }
}